/**
 * 获取目标构造函数字符串，需要注意的是 undefined 和 null 没有构造函数，
 * null 就是原型链查找的最顶层本身是一个空地址，而 undefined 是一个特殊变量
 * @param value
 */
 function getConstructorTypeString(value) {
  return /^\[object (.*?)\]$/.exec(
      Object
      .prototype
      .toString
      .call(value)
    )[1];
}

/**
 * 检查目标构造函数字符串是否是指定类型字符串
 * @param value
 * @param type
 * @example
 * ```
 * checkConstructorTypeString(1, 'Number');
 * true
 * ```
 */
function checkConstructorTypeString(value, type) {
  return getConstructorTypeString(value) === type;
}

/**
 * 目标值类型是否是 null
 * @param value
 */
function isNull(value): value is null {
  return checkConstructorTypeString(value, 'Null');
}

/**
 * 目标值类型是否是 undefined
 * @param value
 */
function isUndefined(value): value is undefined {
  return checkConstructorTypeString(value, 'Undefined');
}

/**
 * 目标值类型是否是 object
 * @param value
 */
function isObject(value): value is Object {
  return checkConstructorTypeString(value, 'Object');
}

/**
 * 目标值类型是否是 number
 * @param value
 */
function isNumber(value): value is Number {
  return checkConstructorTypeString(value, 'Number');
}

/**
 * 目标值类型是否是 string
 * @param value
 */
function isString(value): value is String {
  return checkConstructorTypeString(value, 'String');
}

/**
 * 目标值类型是否是 function
 * @param value
 */
function isFunction(value): value is Function {
  return checkConstructorTypeString(value, 'Function');
}

/**
 * 目标值类型是否是 boolean
 * @param value
 */
function isBoolean(value): value is Boolean {
  return checkConstructorTypeString(value, 'Boolean');
}

/**
 * 目标值类型是否是 array
 * @param value
 */
function isArray(value): value is Array<any> {
  return checkConstructorTypeString(value, 'Array');
}

/**
 * 目标值是否是 nan
 * @param value
 */
function isNaN(value) {
  return Number.isNaN(value);
}

/**
 * 是否是一个有效值（目标不为 null 或 undefined）
 * @param value
 */
function isValidValue(value) {
  return !isNull(value) && !isUndefined(value);
}

function isEmptyChart(value) {
  return isString(value) && value === '';
}

export {
  isNull,
  isUndefined,
  isNumber,
  isString,
  isObject,
  isArray,
  isBoolean,
  isFunction,
  isNaN,
  checkConstructorTypeString,
  isValidValue,
  isEmptyChart
}